﻿using System.Text;
using System.Security.Cryptography;
using Pixeldyne.Core.Extensions;
using Pixeldyne.Core.Text;

namespace Pixeldyne.Core.Security
{
	/// <summary>
	/// Utility wrapper for several hashing (digest) methods.
	/// </summary>
	public class Hasher
	{
		private static readonly Encoding encoding = Encoding.UTF8;

		/// <summary>
		/// Generate a message digest from the specified string
		/// </summary>
		/// <param name="source">the message to hash</param>
		/// <param name="digestType">type of the hashing algorithm</param>
		/// <returns>message digest in hexadecimal form, or string.Empty if error occurs</returns>
		public static string Hash(string source, HashType digestType)
		{
			byte[] sourceBytes = source.ToByteArray(encoding);
			byte[] destBytes = null;

			switch (digestType)
			{
				//case enHashType.FNV24:
				//    destBytes = new FNV1a_24().ComputeHash(source.ToByteArray(encoding));
				//    break;
				//case enHashType.CRC32:
				//    destBytes = new CRC32().ComputeHash(source.ToByteArray(encoding));
				//    break;
				//case enHashType.CRC64:
				//    destBytes = new CRC64().ComputeHash(source.ToByteArray(encoding));
				//    break;
				//case enHashType.ELF32:
				//    destBytes = new ELF32().ComputeHash(source.ToByteArray(encoding));
				//    break;
				case HashType.MD5:
					destBytes = MD5.Create().ComputeHash(sourceBytes);
					break;
				case HashType.RIPEMD160:
					destBytes = RIPEMD160.Create().ComputeHash(sourceBytes);
					break;
				case HashType.SHA1:
					destBytes = SHA1.Create().ComputeHash(sourceBytes);
					break;
				case HashType.SHA256:
					destBytes = SHA256.Create().ComputeHash(sourceBytes);
					break;
				case HashType.SHA512:
					destBytes = SHA512.Create().ComputeHash(sourceBytes);
					break;
				default:
					break;
			}

			return (destBytes == null || destBytes.Length <= 0) ? string.Empty : destBytes.ToHexString();
		}
	}
}
